package org.freemarker;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.common.util.SF;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.StringTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.URLTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
public class FreemarkerUtil {
	private static Configuration cfg;
	private static StringTemplateLoader defaultLoader=new StringTemplateLoader();
	private static final String default_template_name="default_template_name";
	static{
		if(cfg==null){
			initConfiguration();
		}
	}
	public static Configuration getConfiguration(){
		return cfg;
	}
	/**
	 * 初始化配置文件
	 * @return
	 */
	public static void initConfiguration(){
		//TODO 通过Freemaker的Configuration读取相应的ftl
		cfg = new Configuration();
		//TODO 加载模板库
		cfg.setTemplateLoader(getTemplateLoader());
		//TODO 设置UTF编码
		cfg.setDefaultEncoding("UTF-8");
		//加载并设置freemarker.properties  
        Properties p = new Properties();  
        try {
			p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("freemarker.properties"));
			cfg.setSettings(p);
			//cfg.setSetting("auto_import", "\"common/qc.ftl\" as qc");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		//TODO 加载公共属性
		loadCommonProperties();
	}
	/**
	 * 加载公共属性
	 */
	public static void loadCommonProperties(){
		try {
			cfg.setSharedVariable("ftl_time", SF.fdt(new Date()));//时间
			cfg.setSharedVariable("ftl_date", SF.fd(new Date()));//日期
			cfg.setSharedVariable("ftl_dollar","$");//$
			cfg.setSharedVariable("ftl_sharp","#");//#
			cfg.setSharedVariable("ftl_left","{");//{
			cfg.setSharedVariable("ftl_right","}");//}
			cfg.setSharedVariable("ftl_author","garca");//作者
			cfg.setSharedVariable("auto_import", "\"common/qc.ftl\" as qc");
		} catch (TemplateModelException e1) {
			e1.printStackTrace();
		}
	}
	/**
	 * 加载模板库
	 */
	public static TemplateLoader getTemplateLoader(){
		TemplateLoader[] loaders = new TemplateLoader[] {defaultLoader,getClassTemplateLoader(), getMyTemplateLoader()};
		MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
		return mtl;
	}
	/**
	 * 从classpath中加载模板库
	 */
	public static TemplateLoader getClassTemplateLoader(){
		String path="/ftl";
		return new ClassTemplateLoader(String.class, path);
	}
	
	public static TemplateLoader getURLTemplateLoader(){
		
		return new URLTemplateLoader() {
			
			@Override
			protected URL getURL(String name) {
				// TODO Auto-generated method stub
				return null;
			}
		};
	}
	/**
	 * 从文件夹中加载模板库
	 */
	public static TemplateLoader getFileTemplateLoader(){
		File path=new File("E:\\garca\\mission\\qing\\works\\out");
		try {
			return new FileTemplateLoader(path);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return null;
	}
	/**
	 * 根据字符串一个一个加载模板库
	 */
	public static TemplateLoader getStringTemplateLoader(){
		StringTemplateLoader stringLoader = new StringTemplateLoader();  
        String templateContent="欢迎：${name}";  
        stringLoader.putTemplate("myTemplate",templateContent);  
        return stringLoader;
	}
	/**
	 * 获取自定义的模板加载器
	 * @return
	 */
	public static TemplateLoader getMyTemplateLoader(){
		MyTemplateLoader loader=new MyTemplateLoader();
		return loader;
	}
	
	/**
	 * 根据模板名称获取模板
	 * @param name
	 * @return
	 */
	public static Template getTemplate(String name) {
		Template temp=null;
		try {
			temp = cfg.getTemplate(name);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return temp;
	}
	/**
	 * 根据模板名称获取模板
	 * @param name
	 * @return
	 */
	public static Template putTemplate(String name,String template) {
		defaultLoader.putTemplate(name, template);
		Template temp=null;
		try {
			temp = cfg.getTemplate(name);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return temp;
	}
	
	


	public static void run(String name,Object root,Writer wr) {
		try {
			//通过Template可以将模板文件输出到相应的流
			Template temp = getTemplate(name);
			temp.process(root, wr);
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 格式化
	 * @param tpl 字符串模板
	 * @param root 数据
	 * @return
	 */
	public static String format(String tpl,Object root) {
		try {
			//通过Template可以将模板文件输出到相应的流
			Template temp = putTemplate(tpl,tpl);
			StringWriter wt=new StringWriter();
			temp.process(root, wt);
			return wt.getBuffer().toString();
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 模板执行
	 * @param temp
	 * @param root
	 * @param wr
	 */
	public static void print(Template temp,Object root,Writer wr) {
		if(wr==null){
			wr=new OutputStreamWriter(System.out);
		}
		try {
			temp.process(root, wr);
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	
	public static void main(String[] args) {
		Map<String,String> jo=new HashMap<>();
		jo.put("name", "1232");
		//print(putTemplate(default_template_name, "<#assign getSysdate=package org.qc.freemarker.utils.SqlGetSysdateMethod?new()>"), jo, null);
		print(putTemplate("111","${name}Service.javaftl"),jo,new PrintWriter(System.out));
	}
	
	
	
}
